package grpc

import (
	"context"
	"e-commerce/services/auth-service/api/pb"
	"e-commerce/services/auth-service/internal/service"
	"log"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
)

type AuthServer struct {
	pb.UnimplementedAuthServiceServer
	AuthService *service.AuthService
}

func (s *AuthServer) Register(ctx context.Context, req *pb.RegisterRequest) (*pb.RegisterResponse, error) {
	err := s.AuthService.Register(req.Username, req.Password)
	if err != nil {
		return &pb.RegisterResponse{Success: false}, err
	}
	return &pb.RegisterResponse{Success: true}, nil
}

func (s *AuthServer) Login(ctx context.Context, req *pb.LoginRequest) (*pb.LoginResponse, error) {
	token, err := s.AuthService.Login(req.Username, req.Password)
	if err != nil {
		return nil, err
	}
	return &pb.LoginResponse{Token: token}, nil
}

func (s *AuthServer) ValidateToken(ctx context.Context, req *pb.ValidateTokenRequest) (*pb.ValidateTokenResponse, error) {
	valid, userID, role := s.AuthService.ValidateToken(req.Token)
	return &pb.ValidateTokenResponse{Valid: valid, UserId: userID, Role: role}, nil
}

func (s *AuthServer) Logout(ctx context.Context, req *pb.LogoutRequest) (*pb.LogoutResponse, error) {
	err := s.AuthService.Logout(req.Token)
	if err != nil {
		return &pb.LogoutResponse{Success: false}, err
	}
	return &pb.LogoutResponse{Success: true}, nil
}

func NewAuthServer(configPath string) *AuthServer {
	authService, err := service.NewAuthService(configPath)
	if err != nil {
		log.Fatalf("Failed to create auth service: %v", err)
	}
	return &AuthServer{
		AuthService: authService,
	}
}

// 添加token认证中间件
func (s *AuthServer) AuthMiddleware(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
	token := metadata.ValueFromIncomingContext(ctx, "authorization")
	if token == nil {
		return nil, status.Error(codes.Unauthenticated, "missing authorization token")
	}

	valid, _, _ := s.AuthService.ValidateToken(token[0])
	if !valid {
		return nil, status.Error(codes.Unauthenticated, "invalid token")
	}
	return handler(ctx, req)
}
